import React, { Component } from "react";
import "./App.css";
import { dewhite } from './ImageHandler.js';
let canvas;
let ctx;
let ctx2;
let windowSize = {
  width: 800,
  height: 450
};
let picSize = { width: 0, height: 0 };
const offCanvas = document.createElement("canvas");
const offCtx = offCanvas.getContext("2d");
const bgList = {
  green: "rgb(40, 190, 48)",
  blue: "rgb(67, 131, 228)",
  red: "rgb(197, 35, 35)",
  white: "#ffffff",
  black: "#000000"
};
let threshold = 80;
let targetColor = [255, 255, 255];
export class App extends Component {
  img;
  state = {
    select: false,
    background: "green",
    url:'',
    width:1,
    height:1
  };
  render() {
    return (
      <div className="App" ref="app">
        <div className="button-group">
          <button onClick={() => this.changeBG("red")}>红背景</button>
          <button onClick={() => this.changeBG("blue")}>蓝背景</button>
          <button onClick={() => this.changeBG("green")}>绿背景</button>
          <button onClick={() => this.changeBG("white")}>白背景</button>
          <button onClick={() => this.changeBG("black")}>黑背景</button>
        </div>
        <div className="value-input">
          阈值:
          <input
            type="number"
            defaultValue={threshold}
            onChange={e => {
              threshold = +e.target.value;
              this.renderCanvas();
            }}
          />
        </div>
        <div
          className="image-button"
          onClick={() => this.refs.input.click()}
          style={{ background: bgList[this.state.background] }}
        >
          <img src={this.state.url} style={{width:this.state.width,height:this.state.height}}></img>
          {!this.state.select && <div className="title">选择图片</div>}
        </div>
        <div
          className="image-button"
          style={{ background: bgList[this.state.background] }}
        >
          <canvas
            ref="canvas2"
            width={windowSize.width}
            height={windowSize.height}
          ></canvas>
          {!this.state.select && <div className="title">原图对照</div>}
          <canvas
            ref="canvas"
            width={windowSize.width}
            height={windowSize.height}
          ></canvas>
        </div>
        <input
          hidden={true}
          ref="input"
          type="file"
          accept="image/*"
          onChange={e => {
            this.setState({
              select: true
            });
            const source = e.target.files[0];
            if (!source) return;
            const src = URL.createObjectURL(source);
            this.img.src = src;
            this.img.onload = this.renderCanvas;
          }}
        ></input>
      </div>
    );
  }
  constructor(props) {
    super(props);
    this.img = new Image();
  }
  componentDidMount() {
    canvas = this.refs.canvas;
    ctx = canvas.getContext("2d");
    ctx2 = this.refs.canvas2.getContext("2d");
  }

  renderCanvas = () => {
    ctx.clearRect(0, 0, windowSize.width, windowSize.height);
    ctx2.clearRect(0, 0, windowSize.width, windowSize.height);
    let { width, height } = this.img;
    if (width > windowSize.width) {
      height = (height * windowSize.width) / width;
      width = windowSize.width;
    }
    if (height > windowSize.height) {
      width = (width * windowSize.height) / height;
      height = windowSize.height;
    }
    picSize = {
      width,
      height
    };
    this.setState({width,height})
    // ctx.drawImage(this.img, 0, 0, width, height);
    offCanvas.height = height;
    offCanvas.width = width;
    // offCtx.drawImage(this.img, 0, 0, width, height);
    ctx2.drawImage(this.img, 0, 0, width, height);
    dewhite(this.img.src).then(res=>{
      const url=URL.createObjectURL(res);
      this.setState({url})
    })
    // this.opacityHandler();
  };
  opacityHandler = () => {
    const { width, height } = picSize;

    const image = offCtx.getImageData(0, 0, width, height);
    const imageData = image.data;
    const length = width * height;
    //去色
    //遍历像素找到最大颜色距离
    let maxDis = 0;
    for (let i = 0; i < length; i += 10) {
      const rgba = getPixByIndex(imageData, i);
      const pixDistance = getColorDistance(rgba, targetColor);
      if (pixDistance > maxDis) maxDis = pixDistance;
    }
    for (let i = 0; i < length; i++) {
      const rgba = getPixByIndex(imageData, i);
      const pixDistance = getColorDistance(rgba, targetColor);
      if (pixDistance < threshold) {
        imageData[i * 4 + 0] = 255;
        imageData[i * 4 + 1] = 255;
        imageData[i * 4 + 2] = 255;
        imageData[i * 4 + 3] = 0;
      } else if (pixDistance < maxDis / 2) {
        imageData[i * 4 + 3] = (pixDistance / maxDis) * 255;
      }
    }

    for (let i = 0; i < length; i+=1) {
      const [r,g,b] = getPixByIndex(imageData, i);
      const [x, y] = getXYByIndex(i);
      const nearList = getNearMatrix(imageData, x, y, 2);
      // eslint-disable-next-line no-loop-func
      nearList.forEach(item => {
        if (item.disNear < threshold && item.disTarget > threshold) {
          imageData[i * 4 + 0] = r;
          imageData[i * 4 + 1] = g;
          imageData[i * 4 + 2] = b;
          imageData[i * 4 + 3] = 255;
        }
      });
    }
    ctx.putImageData(image, 0, 0);
  };
  changeBG = mode => {
    this.setState({
      background: mode
    });
  };
}

export default App;
const getPix = (imgData, x = 0, y = 0, width = picSize.width) => {
  const start = getPixPropIndex(x, y, width);
  return imgData.slice(start, start + 4);
};
const getPixByIndex = (imgData, index) => {
  return imgData.slice(index * 4, (index + 1) * 4);
};
const getPixPropIndex = (x, y, width = picSize.width) => {
  return (y * width + x) * 4;
};
const getXYByIndex = (index, width = picSize.width) => {
  const y = parseInt(index / width, 10);
  const x = index - y * width;
  return [x, y];
};
const getColorDistance = (rgb, target) => {
  const [r1, g1, b1] = rgb;
  const [r2, g2, b2] = target;
  return Math.sqrt(
    Math.pow(r1 - r2, 2) * 1 +
      Math.pow(g1 - g2, 2) * 1.15 +
      Math.pow(b1 - b2, 2) * 1.15
  );
};
const getNearMatrix = (
  imageData,
  x,
  y,
  delta,
  width = picSize.width,
  height = picSize.height
) => {
  const pixList = [];
  const rgba = getPix(imageData, x, y);
  let startX = x - delta;
  let endX = x + delta + 1;
  let startY = y - delta;
  let endY = y + delta + 1;
  if (startX < 0) startX = 0;
  if (endX > width) endX = width;
  if (startY < 0) startY = 0;
  if (endY > height) endY = height;
  for (let i = startX; i < endX; i++) {
    for (let j = startY; j < endY; j++) {
      if (i === x && j === y) continue;
      const pix = getPix(imageData, i, j);
      const disNear = getColorDistance(pix, rgba);
      const disTarget = getColorDistance(pix, targetColor);
      pixList.push({ pix, disNear, disTarget });
    }
  }
  return pixList;
};
